js复制内容到剪切板踩到的坑

您所在的位置:网站首页 js 复制粘贴 js复制内容到剪切板踩到的坑

js复制内容到剪切板踩到的坑

2023-08-25 02:29| 来源: 网络整理| 查看: 265

这是我参与更文挑战的第1天,活动详情查看: 更文挑战

问题

最近在app弄一个h5活动,需要复制券码,使用的是之前的封装的复制函数;

原理是通过创建一个input元素,把它的value设置成复制的文本;然后调用select方法选中,再执document.execCommand('copy')复制到剪切板,最后把该元素删除,这里需要注意

input 需要设置readonly,防止执行select时由于光标聚焦出现页面抖动;

代码如下:

/** * 复制文本 * @param {string} text 复制的文本 */ copyText (text) { const input = document.createElement('input') document.body.appendChild(input) input.setAttribute('readonly', 'readonly') input.setAttribute('value', text) input.select() try { document.execCommand('copy') } catch (err) { } document.body.removeChild(input) }

三下五除二,一把梭没什么难度,然后本地测试没问题后,提交测试。

不料,临近上线的时候,测试提了一个问题,在ios12的手机上不能实现复制,安卓正常;

image.png

探索

初步推断是兼容性问题;

于是我google查了一下(百度你懂的),原来是ios部分机型不支持input.select()方法,导致无法选中,所以无法执行document.execCommand('copy')复制操作;

那咋办?

网上有人推荐使用clipboard.js,我就在想,既然clipboard.js这么多人用,它应该有解决这个问题;于是乎我去到github看看它的源码,了解下是怎么解决的

搜索一番后,果然有所获;

image.png

研究

clipboard.js内部用了一个select的npm包;这个包主要是去选中复制的内容

摘取部分核心代码展示:

var isReadOnly = element.hasAttribute('readonly'); if (!isReadOnly) { element.setAttribute('readonly', ''); } element.select(); element.setSelectionRange(0, element.value.length); //重点是这句话 if (!isReadOnly) { element.removeAttribute('readonly'); }

发现了吗?他跟我上面的代码主要是多了element.setSelectionRange(0, element.value.length);

原来如此,通过文本选区去选中文本,妙啊;

mdn的解释:

HTMLInputElement.setSelectionRange 方法用于设定 或 元素中当前选中文本的起始和结束位置。

HTMLInputElement.setSelectionRange(selectionStart, selectionEnd [, selectionDirection]);

接受三个参数; 第一个参数:字符串开始索引 第二个参数:字符串结束索引 第三个参数:表示选择方向的字符串,可选值有 forward: 从开头开始选 backward: 从结尾开始选 none: 默认值,表示方向未定

大家可以通过setSelectionRange这个链接查看更多内容

解决方法

最后我加上这个setSelectionRange方法,测试通过,ios和安卓都正常;

完整代码如下:

/** * 复制文本 * @param {string} text 复制的文本 */ copyText (text) { const input = document.createElement('input') document.body.appendChild(input) input.setAttribute('readonly', 'readonly') input.setAttribute('value', text) input.select() input.setSelectionRange(0, text.length) try { document.execCommand('copy') } catch (err) { } document.body.removeChild(input) } 总结:

如果你不想折腾,可以直接使用clipboard.js这个库,但是我自己想折腾一下,不想又多引入一个库,那就折腾起来吧~

如果有任何看法,欢迎评论留言~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3